package com.teach.javafxclient.controller.base;

import com.teach.javafxclient.Globalvar;
import com.teach.javafxclient.MainApplication;
import com.teach.javafxclient.util.HttpUtil;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import kong.unirest.HttpResponse;
import kong.unirest.JsonNode;
import kong.unirest.json.JSONArray;
import kong.unirest.json.JSONObject;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

public class CoursePageController {
    @FXML
    public Button addCourse;
    @FXML
    private AnchorPane pageRoot;
    private TabPane tabNode;
    private FXMLLoader tabLoader;
    private TabPaneController tabC;
    @FXML
    public VBox subContent;
    @FXML
    private ComboBox<String> sortCombobox;
    @FXML
    private GridPane gridPane;
    @FXML
    private CheckBox checkBox1, checkBox2, checkBox3;
    @FXML
    private AnchorPane anchorPane, anchorPane1;
    @FXML
    private Label courseNumber, courseNumber0, creditNumber, creditNumber0, label0;
    @FXML
    private Button courseButton, button1, button2, temp;
    @FXML
    private HBox hbox1, hbox2, anchor1Hbox1, anchor1Hbox2, anchor2Hbox1, anchor2Hbox2;
    private double creditSum = 0.0;
    private Button selectedButton;
    private int j = 1;

    public void studyButtonClicked() {
        hbox1.setVisible(true);
        hbox2.setVisible(false);
    }

    public void courseButtonClicked() {
        hbox1.setVisible(true);
        hbox2.setVisible(true);
    }

    public void initialize() {
        checkBox1.setSelected(true);
        checkBox2.setSelected(true);
        checkBox3.setSelected(true);
        addCourse.setOnAction(e -> {
            if (subContent.getChildren().isEmpty()) {
                tabLoader = new FXMLLoader(MainApplication.class.getResource("base/tab-pane.fxml"));
                try {
                    tabNode = tabLoader.load();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
                ChangeListener<Number> widthListener;
                widthListener = (observable, oldValue, newValue) -> {
                    Double pageWidth = newValue.doubleValue();
                    pageRoot.setPrefWidth(pageWidth * 0.52);
                    subContent.setPrefWidth(pageWidth * 0.40);
                };
                pageRoot.widthProperty().addListener(widthListener);
                tabC = tabLoader.getController();
                subContent.getChildren().add(tabNode);
            }
            FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("base/course-register.fxml"));
            Scene scene;
            try {
                Parent courseRegisterPage = fxmlLoader.load();
                scene = new Scene(courseRegisterPage);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
            tabC.changeContentByScene(scene, "base/course-register", "注册课程");
        });

        // 初始化ComboBox，默认选中“按学分”
        ObservableList<String> items = FXCollections.observableArrayList("按学分", "按课程名首字母", "按课程号");
        sortCombobox.setItems(items);
        sortCombobox.getSelectionModel().select("按学分");

        // 为按钮1添加事件处理器
        button1.setOnAction(e -> changeContent(button1));
        // 为按钮2添加事件处理器
        button2.setOnAction(e -> changeContent(button2));

        // 为三个 CheckBox 添加监听器
        checkBox1.selectedProperty().addListener((observable, oldValue, newValue) -> {
            handleComboBoxAndCheckboxChange(j);
        });

        checkBox2.selectedProperty().addListener((observable, oldValue, newValue) -> {
            handleComboBoxAndCheckboxChange(j);
        });

        checkBox3.selectedProperty().addListener((observable, oldValue, newValue) -> {
            handleComboBoxAndCheckboxChange(j);
        });

        // ComboBox 选项改变时的监听器
        sortCombobox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            handleComboBoxAndCheckboxChange(j);
        });
    }

    public void Button1Clicked() {
        hbox2.setVisible(true);
    }

    public void Button2Clicked() {
        hbox2.setVisible(true);
    }

    protected void changeContent(Button button) {
        hbox2.setVisible(true);
        if (button == selectedButton) {
            button.setStyle("-fx-text-fill: #5b5c5c");
            selectedButton = null;
        } else {
            if (selectedButton != null) {
                selectedButton.setStyle("-fx-text-fill: #5b5c5c");
            }
            button.setStyle("-fx-text-fill: #670202");
            selectedButton = button;
        }
        performOperationOnSelection(button);
    }

    private void performOperationOnSelection(Button button) {
        if (button == button1) {
            handleComboBoxAndCheckboxChange(1);
        } else if (button == button2) {
            handleComboBoxAndCheckboxChange(2);
        }
    }

    private void handleComboBoxAndCheckboxChange(int x) {
        creditSum = 0.0;
        j = x;
        int i = 1; // 默认按学分
        if (checkBox1.isSelected() || checkBox2.isSelected() || checkBox3.isSelected()) {
            i = sortCombobox.getSelectionModel().getSelectedIndex() + 1;
        }
        handleCheckboxChange(i, j);
    }

    private void handleCheckboxChange(int i, int j) {
        boolean checked1 = checkBox1.isSelected();
        boolean checked2 = checkBox2.isSelected();
        boolean checked3 = checkBox3.isSelected();
        if (checked1 && !checked2 && !checked3) {
            handleEventA(i, j);
        } else if (!checked1 && checked2 && checked3) {
            handleEventB(i, j);
        } else if (checked1 && checked2 && !checked3) {
            handleEventC(i, j);
        } else if (checked1 && !checked2 && checked3) {
            handleEventD(i, j);
        } else if (!checked1 && checked2 && !checked3) {
            handleEventE(i, j);
        } else if (!checked1 && !checked2 && checked3) {
            handleEventF(i, j);
        } else if (checked1 && checked2 && checked3) {
            handleEventG(i, j);
        } else {
            handleEventH(i, j);
        }
    }

    private HttpResponse<JsonNode> repeat(int i, int j) {
        HttpResponse<JsonNode> response = null;
        String u1 = Globalvar.baseUrl + "/api/courses?sortType=CREDIT&termld=1&collegeld=1";
        String u2 = Globalvar.baseUrl + "/api/courses?sortType=NAME&termld=1&collegeld=1";
        String u3 = Globalvar.baseUrl + "/api/courses?sortType=ID&termld=1&collegeld=1";
        if (i == 1) {
            if (j == 1) {
                response = HttpUtil.get(u1 + "&ended=false")
                        .header("Accept", "application/json")
                        .asJson();
            } else if (j == 2) {
                response = HttpUtil.get(u1 + "&ended=true")
                        .header("Accept", "application/json")
                        .asJson();
            }
        } else if (i == 2) {
            if (j == 1) {
                response = HttpUtil.get(u2 + "&ended=false")
                        .header("Accept", "application/json")
                        .asJson();
            } else if (j == 2) {
                response = HttpUtil.get(u2 + "&ended=true")
                        .header("Accept", "application/json")
                        .asJson();
            }
        } else if (i == 3) {
            if (j == 1) {
                response = HttpUtil.get(u3 + "&ended=false")
                        .header("Accept", "application/json")
                        .asJson();
            } else if (j == 2) {
                response = HttpUtil.get(u3 + "&ended=true")
                        .header("Accept", "application/json")
                        .asJson();
            }
        }
        return response;
    }

    // 必修
    private void handleEventA(int i, int j) {
        Map<String, VBox> map = new LinkedHashMap<>();
        HttpResponse<JsonNode> response = repeat(i, j);
        if (response != null) {
            JsonNode responseBody = response.getBody();
            JSONArray jsonArray = responseBody.getArray();
            for (int h = 0; h < jsonArray.length(); h++) {
                JSONObject jsonObject = jsonArray.getJSONObject(h);
                String type = jsonObject.getString("type");
                String name = jsonObject.getString("name");
                String teacherName = jsonObject.getString("teacherName");
                String courseId = jsonObject.getString("courseId");
                String location = jsonObject.getString("location");
                double credit0 = Double.parseDouble(jsonObject.getString("credit"));
                BigDecimal credit = new BigDecimal(credit0);
                if (Objects.equals(type, "通识核心课") || Objects.equals(type, "专业基础课") || Objects.equals(type, "学科基础课")) {
                    VBox vbox = createVBox(type, name, teacherName, location, credit, courseId);
                    creditSum += credit0;
                    map.put(courseId, vbox);
                }
            }
        }
        gridPane(map);
    }

    // 限选+选修
    private void handleEventB(int i, int j) {
        Map<String, VBox> map = new LinkedHashMap<>();
        HttpResponse<JsonNode> response = repeat(i, j);
        if (response != null) {
            JsonNode responseBody = response.getBody();
            JSONArray jsonArray = responseBody.getArray();
            for (int h = 0; h < jsonArray.length(); h++) {
                JSONObject jsonObject = jsonArray.getJSONObject(h);
                String type = jsonObject.getString("type");
                String name = jsonObject.getString("name");
                String teacherName = jsonObject.getString("teacherName");
                String courseId = jsonObject.getString("courseId");
                String location = jsonObject.getString("location");
                double credit0 = Double.parseDouble(jsonObject.getString("credit"));
                BigDecimal credit = new BigDecimal(credit0);
                if (Objects.equals(type, "通识选修课") || Objects.equals(type, "专业限选课")) {
                    VBox vbox = createVBox(type, name, teacherName, location, credit, courseId);
                    creditSum += credit0;
                    map.put(courseId, vbox);
                }
            }
        }
        gridPane(map);
    }

    // 必修+限选
    private void handleEventC(int i, int j) {
        Map<String, VBox> map = new LinkedHashMap<>();
        HttpResponse<JsonNode> response = repeat(i, j);
        if (response != null) {
            JsonNode responseBody = response.getBody();
            JSONArray jsonArray = responseBody.getArray();
            for (int h = 0; h < jsonArray.length(); h++) {
                JSONObject jsonObject = jsonArray.getJSONObject(h);
                String type = jsonObject.getString("type");
                String name = jsonObject.getString("name");
                String teacherName = jsonObject.getString("teacherName");
                String courseId = jsonObject.getString("courseId");
                String location = jsonObject.getString("location");
                double credit0 = Double.parseDouble(jsonObject.getString("credit"));
                BigDecimal credit = new BigDecimal(credit0);
                if (Objects.equals(type, "通识核心课") || Objects.equals(type, "专业基础课") || Objects.equals(type, "学科基础课") || Objects.equals(type, "专业限选课")) {
                    VBox vbox = createVBox(type, name, teacherName, location, credit, courseId);
                    creditSum += credit0;
                    map.put(courseId, vbox);
                }
            }
        }
        gridPane(map);
    }

    // 必修+选修
    private void handleEventD(int i, int j) {
        Map<String, VBox> map = new LinkedHashMap<>();
        HttpResponse<JsonNode> response = repeat(i, j);
        if (response != null) {
            JsonNode responseBody = response.getBody();
            JSONArray jsonArray = responseBody.getArray();
            for (int h = 0; h < jsonArray.length(); h++) {
                JSONObject jsonObject = jsonArray.getJSONObject(h);
                String type = jsonObject.getString("type");
                String name = jsonObject.getString("name");
                String teacherName = jsonObject.getString("teacherName");
                String courseId = jsonObject.getString("courseId");
                String location = jsonObject.getString("location");
                double credit0 = Double.parseDouble(jsonObject.getString("credit"));
                BigDecimal credit = new BigDecimal(credit0);
                if (Objects.equals(type, "通识核心课") || Objects.equals(type, "专业基础课") || Objects.equals(type, "学科基础课") || Objects.equals(type, "通识选修课")) {
                    VBox vbox = createVBox(type, name, teacherName, location, credit, courseId);
                    creditSum += credit0;
                    map.put(courseId, vbox);
                }
            }
        }
        gridPane(map);
    }

    // 限选
    private void handleEventE(int i, int j) {
        Map<String, VBox> map = new LinkedHashMap<>();
        HttpResponse<JsonNode> response = repeat(i, j);
        if (response != null) {
            JsonNode responseBody = response.getBody();
            JSONArray jsonArray = responseBody.getArray();
            for (int h = 0; h < jsonArray.length(); h++) {
                JSONObject jsonObject = jsonArray.getJSONObject(h);
                String type = jsonObject.getString("type");
                String name = jsonObject.getString("name");
                String teacherName = jsonObject.getString("teacherName");
                String courseId = jsonObject.getString("courseId");
                String location = jsonObject.getString("location");
                double credit0 = Double.parseDouble(jsonObject.getString("credit"));
                BigDecimal credit = new BigDecimal(credit0);
                if (Objects.equals(type, "专业限选课")) {
                    VBox vbox = createVBox(type, name, teacherName, location, credit, courseId);
                    creditSum += credit0;
                    map.put(courseId, vbox);
                }
            }
        }
        gridPane(map);
    }

    // 选修
    private void handleEventF(int i, int j) {
        Map<String, VBox> map = new LinkedHashMap<>();
        HttpResponse<JsonNode> response = repeat(i, j);
        if (response != null) {
            JsonNode responseBody = response.getBody();
            JSONArray jsonArray = responseBody.getArray();
            for (int h = 0; h < jsonArray.length(); h++) {
                JSONObject jsonObject = jsonArray.getJSONObject(h);
                String type = jsonObject.getString("type");
                String name = jsonObject.getString("name");
                String teacherName = jsonObject.getString("teacherName");
                String courseId = jsonObject.getString("courseId");
                String location = jsonObject.getString("location");
                double credit0 = Double.parseDouble(jsonObject.getString("credit"));
                BigDecimal credit = new BigDecimal(credit0);
                if (Objects.equals(type, "通识选修课")) {
                    VBox vbox = createVBox(type, name, teacherName, location, credit, courseId);
                    creditSum += credit0;
                    map.put(courseId, vbox);
                }
            }
        }
        gridPane(map);
    }

    // 必修+限选+选修
    private void handleEventG(int i, int j) {
        Map<String, VBox> map = new LinkedHashMap<>();
        HttpResponse<JsonNode> response = repeat(i, j);
        if (response != null) {
            JsonNode responseBody = response.getBody();
            JSONArray jsonArray = responseBody.getArray();
            for (int h = 0; h < jsonArray.length(); h++) {
                JSONObject jsonObject = jsonArray.getJSONObject(h);
                String type = jsonObject.getString("type");
                String name = jsonObject.getString("name");
                String teacherName = jsonObject.getString("teacherName");
                String courseId = jsonObject.getString("courseId");
                String location = jsonObject.getString("location");
                double credit0 = Double.parseDouble(jsonObject.getString("credit"));
                BigDecimal credit = new BigDecimal(credit0);
                if (Objects.equals(type, "通识核心课") || Objects.equals(type, "专业基础课") || Objects.equals(type, "学科基础课") || Objects.equals(type, "专业限选课") || Objects.equals(type, "通识选修课")) {
                    VBox vbox = createVBox(type, name, teacherName, location, credit, courseId);
                    creditSum += credit0;
                    map.put(courseId, vbox);
                }
            }
        }
        gridPane(map);
    }

    // 都没选
    private void handleEventH(int i, int j) {
        gridPane.getChildren().clear();
        courseNumber.setText("0");
        courseNumber0.setText("0");
        creditNumber.setText("0.0");
        creditNumber0.setText("0.0");
    }

    private void gridPane(Map<String, VBox> map) {
        gridPane.getChildren().clear();
        int col = 0;
        int row = 0;
        double rowHeight = 70.0;
        double commonRowSpacing = 20.0;

        for (VBox vbox : map.values()) {
            gridPane.add(vbox, col, row);

            col++;
            if (col == gridPane.getColumnCount()) {
                col = 0;
                row++;

                RowConstraints rowConstraints = new RowConstraints();
                rowConstraints.setMinHeight(rowHeight);
                rowConstraints.setPrefHeight(rowHeight);
                rowConstraints.setVgrow(Priority.SOMETIMES);
                gridPane.getRowConstraints().add(rowConstraints);

//                if (row > 1) {
//                    Region spacer = new Region();
//                    gridPane.add(spacer, 0, row);
//                    rowConstraints = new RowConstraints();
//                    rowConstraints.setPrefHeight(commonRowSpacing);
//                    gridPane.getRowConstraints().add(rowConstraints);
//                    GridPane.setColumnSpan(spacer, gridPane.getColumnCount());
                }
            }
   //     }
        double totalHeight = (gridPane.getRowConstraints().size() * rowHeight) + ((gridPane.getRowConstraints().size() - 1) * commonRowSpacing);
        gridPane.setPrefHeight(totalHeight);
    }

    private Map<String, Scene> courseScenes = new HashMap<>();

    private VBox createVBox(String s0, String s1, String s2, String s3, BigDecimal s4, String courseId) {
        VBox vbox = new VBox();
        vbox.setPrefHeight(60.0);
        vbox.setPrefWidth(230.0);
        switch (s0) {
            case "学科基础课":
                vbox.setStyle("-fx-background-color: #fae3e3; -fx-background-radius: 6;");
                break;
            case "专业基础课":
                vbox.setStyle("-fx-background-color: #d6e8ff; -fx-background-radius: 6;");
                break;
            case "通识核心课":
                vbox.setStyle("-fx-background-color: #cef3c7; -fx-background-radius: 6;");
                break;
            case "专业限选课":
                vbox.setStyle("-fx-background-color: #fcffc9; -fx-background-radius: 6;");
                break;
            case "通识选修课":
                vbox.setStyle("-fx-background-color: #fbeeff; -fx-background-radius: 6;");
                break;
        }
        gridPane.setHgap(22);
        gridPane.setVgap(15);

        Label label = new Label();
        label.setText(s1);
        label.setPrefHeight(29.0);
        label.setPrefWidth(119.0);
        VBox.setMargin(label, new Insets(9.0, 0.0, 0.0, 25.0));
        label.setFont(new Font(12.0));

        HBox hbox = new HBox();
        hbox.setPrefHeight(31.0);
        hbox.setPrefWidth(239.0);
        VBox.setMargin(hbox, new Insets(-5.0, 0.0, 2.0, 10.0));

        String imagePath1 = getClass().getResource("/com/teach/javafxclient/picture/canva-MAE-aIJL37c.png").toExternalForm();
        Image image1 = new Image(imagePath1);
        ImageView imageView1 = new ImageView(image1);
        imageView1.setFitHeight(14.0);
        imageView1.setFitWidth(9.0);
        HBox.setMargin(imageView1, new Insets(7.0, 0.0, 0.0, 15.0));

        Label label1 = new Label();
        label1.setText(s2);
        label1.setPrefHeight(14.0);
        label1.setPrefWidth(38.0);
        HBox.setMargin(label1, new Insets(8.0, 0.0, 0.0, 5.0));
        label1.setFont(new Font(10.0));

        String imagePath2 = getClass().getResource("/com/teach/javafxclient/picture/canva-pin-location-with-map-flat-icon-MAEVKlQ-g2Y.png").toExternalForm();
        Image image2 = new Image(imagePath2);
        ImageView imageView2 = new ImageView(image2);
        imageView2.setFitHeight(14.0);
        imageView2.setFitWidth(14.0);
        HBox.setMargin(imageView2, new Insets(8.0, 0.0, 0.0, 12.0));

        Label label2 = new Label();
        label2.setText(s3);
        label2.setPrefHeight(14.0);
        label2.setPrefWidth(60.0);
        HBox.setMargin(label2, new Insets(8.0, 0.0, 0.0, 4.0));
        label2.setFont(new Font(10.0));

        String imagePath3 = getClass().getResource("/com/teach/javafxclient/picture/canva-MAEVLS_eBnE.png").toExternalForm();
        Image image3 = new Image(imagePath3);
        ImageView imageView3 = new ImageView(image3);
        imageView3.setFitHeight(10.0);
        imageView3.setFitWidth(15.0);
        HBox.setMargin(imageView3, new Insets(11.0, 0.0, 0.0, 20.0));

        Label label3 = new Label();
        String str4 = s4 + "学分";
        label3.setText(str4);
        label3.setPrefHeight(14.0);
        label3.setPrefWidth(38.0);
        HBox.setMargin(label3, new Insets(8.0, 0.0, 0.0, 5.0));
        label3.setFont(new Font(10.0));

        hbox.getChildren().addAll(imageView1, label1, imageView2, label2, imageView3, label3);
        vbox.getChildren().addAll(label, hbox);
        vbox.setOnMouseClicked(e -> {
            if (subContent.getChildren().isEmpty()) {
                tabLoader = new FXMLLoader(MainApplication.class.getResource("base/tab-pane.fxml"));
                try {
                    tabNode = tabLoader.load();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
                ChangeListener<Number> widthListener;
                widthListener = (observable, oldValue, newValue) -> {
                    Double pageWidth = newValue.doubleValue();
                    subContent.setPrefWidth(pageWidth * 0.35);
                };
                pageRoot.widthProperty().addListener(widthListener);
                tabC = tabLoader.getController();
                subContent.getChildren().add(tabNode);
            }
            Scene scene = courseScenes.get(courseId);
            if (scene == null) {
                FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("base/course-info.fxml"));
                Parent root;
                try {
                    root = fxmlLoader.load();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
                CourseInfoController CIC = fxmlLoader.getController();
                CIC.setCourseInfo(courseId);
                scene = new Scene(root);
                tabC.changeContentByScene(scene, "base/student-info", s1);
                courseScenes.put(courseId, scene);
            } else {
                tabC.changeContentByScene(scene, "base/student-info", s1);

            }
        });
        return vbox;
    }
}
